	/**
	 * Demo binding and preparation, no need to read this part
	 */
	//borrowed from jQuery easing plugin
	//http://gsgd.co.uk/sandbox/jquery.easing.php
jQuery.easing['jswing'] = jQuery.easing['swing'];

jQuery.extend( jQuery.easing,
{
	def: 'easeOutQuad',
	swing: function (x, t, b, c, d) {
		//alert(jQuery.easing.default);
		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
	},
	easeInQuad: function (x, t, b, c, d) {
		return c*(t/=d)*t + b;
	},
	easeOutQuad: function (x, t, b, c, d) {
		return -c *(t/=d)*(t-2) + b;
	},
	easeInOutQuad: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t + b;
		return -c/2 * ((--t)*(t-2) - 1) + b;
	},
	easeInCubic: function (x, t, b, c, d) {
		return c*(t/=d)*t*t + b;
	},
	easeOutCubic: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t + 1) + b;
	},
	easeInOutCubic: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t + b;
		return c/2*((t-=2)*t*t + 2) + b;
	},
	easeInQuart: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t + b;
	},
	easeOutQuart: function (x, t, b, c, d) {
		return -c * ((t=t/d-1)*t*t*t - 1) + b;
	},
	easeInOutQuart: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
		return -c/2 * ((t-=2)*t*t*t - 2) + b;
	},
	easeInQuint: function (x, t, b, c, d) {
		return c*(t/=d)*t*t*t*t + b;
	},
	easeOutQuint: function (x, t, b, c, d) {
		return c*((t=t/d-1)*t*t*t*t + 1) + b;
	},
	easeInOutQuint: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
		return c/2*((t-=2)*t*t*t*t + 2) + b;
	},
	easeInSine: function (x, t, b, c, d) {
		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
	},
	easeOutSine: function (x, t, b, c, d) {
		return c * Math.sin(t/d * (Math.PI/2)) + b;
	},
	easeInOutSine: function (x, t, b, c, d) {
		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
	},
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	},
	easeInCirc: function (x, t, b, c, d) {
		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
	},
	easeOutCirc: function (x, t, b, c, d) {
		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
	},
	easeInOutCirc: function (x, t, b, c, d) {
		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
	},
	easeInElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
	},
	easeOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
	},
	easeInOutElastic: function (x, t, b, c, d) {
		var s=1.70158;var p=0;var a=c;
		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
		if (a < Math.abs(c)) { a=c; var s=p/4; }
		else var s = p/(2*Math.PI) * Math.asin (c/a);
		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
	},
	easeInBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*(t/=d)*t*((s+1)*t - s) + b;
	},
	easeOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158;
		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
	},
	easeInOutBack: function (x, t, b, c, d, s) {
		if (s == undefined) s = 1.70158; 
		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
	},
	easeInBounce: function (x, t, b, c, d) {
		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
	},
	easeOutBounce: function (x, t, b, c, d) {
		if ((t/=d) < (1/2.75)) {
			return c*(7.5625*t*t) + b;
		} else if (t < (2/2.75)) {
			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
		} else if (t < (2.5/2.75)) {
			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
		} else {
			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
		}
	},
	easeInOutBounce: function (x, t, b, c, d) {
		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
	}
});

//ebook render
var ebook = (function (){
	var opt = {},pn;
	opt.lineNum = 30;
	opt.lineHeight = 2;//em
	opt.container = $('#page-box');
	opt.nav = $('#pager .all');
    //debug
	var db = function() { 'console' in window && console.log.call(console, arguments); };
	var utils = {
		isinpn : function (pos,pn){
			var _isinpn = true;
			var pnlines = opt.lineNum;
			var _pn={};
			_pn.start = pnlines * pn;
			_pn.end = pnlines * (pn+1);
			
			if(pos.start >= _pn.end || pos.end <= _pn.start){
				_isinpn = false;
			}
			return _isinpn;
		},
		go2page : function(idx){
			$.scrollTo( '#item'+idx, 700 , {easing:'easeOutQuad'});
	  		window.location.hash = 'item'+idx;
	  		opt.nav.data('index',idx);
		},
		go2page2 : function(idx){
			var ems = idx*55;
			var cssrule = {'left' : '-'+ems+'em'};
			$('#page-box').css(cssrule);
			window.location.hash = 'item'+idx;
	  		opt.nav.data('index',idx);
		},
		gethash : function(e){
			var el= $(e.target), href = el.attr('href');
	        if (!href) {
	          return;
	        }
	        hash = href.split('#')[1].toLowerCase();
			return hash;
		}
	};
	var s = parseInt($('html').css('fontSize').replace('px',''));
	var renderPage = function(html){
        //render first page get pagenum
        
		var pageItem = '<div class="page-item"><div class="page-hd"></div><div class="page-bd"><div class="data">'+html+'</div></div><div class="page-ft"></div></div>';
		opt.container.html('');
		$(pageItem).appendTo(opt.container);
		var allHeight = opt.container.find('.data').innerHeight() / s;
		var perHeight = opt.lineHeight * opt.lineNum;
		pn = Math.ceil(allHeight/perHeight);
		
        //creat other pages
		for (var i = 1 ; i <= pn ; i++) {
			var _str = [];
			_str.push('<div class="page-item" id="item'+ i +'">');
			_str.push('<div class="page-hd"></div><div class="page-bd"><div class="data"></div></div>');
			_str.push('<div class="page-ft">第' + i +'页</div>');
			_str.push('</div>');
			$(_str.join('')).appendTo(opt.container);
		}

        //get paragraph data
		var paragraph  = [];
		opt.container.find('.line').each(function(){
			var pos = {};
			var par_top = parseInt($(this).position().top);
			// a paragraph has attr margin-bottom eq line-height
			var par_btm = par_top + parseInt($(this).height());
			
			//the start line
			pos.start = par_top/(s * opt.lineHeight);
			//the end line
			pos.end = par_btm/(s * opt.lineHeight);
			paragraph.push(pos);
		});
		
		
		//get page's paragraph
		for(var j=0,len = paragraph.length;j<len;j++){
			paragraph[j]['pn'] = [];
			for(var i = 0 ; i < pn ; i ++){
				var isin = utils.isinpn(paragraph[j],i);
				if(isin){
					paragraph[j]['pn'].push(i+1);
				}
			}
		}
		//get paragraph's hidden lines
		for(var j=0,len = paragraph.length;j<len;j++){
			var pnlines = opt.lineNum;
			if(paragraph[j]['pn'].length === 2){
				var pn_endline = pnlines * (paragraph[j]['pn'][0]);
				var par_startline = paragraph[j].start;
				var hid_lines = pn_endline - par_startline;
				paragraph[j]['hidlines'] = hid_lines;
			}
		}
		
		//render all pages
		opt.container.find('.line').each(function(j){
			var __pn = paragraph[j]['pn'];
			$(this).clone().appendTo(opt.container.find('.data').eq(__pn[0]));
			if(paragraph[j]['pn'].length === 2){				
				$(this).clone().appendTo(opt.container.find('.data').eq(__pn[1]));
				$(opt.container.find('.data').get(__pn[1])).data('hidlines',paragraph[j]['hidlines']);
			}
		});
		//remove temp page
		$(opt.container.find('.page-item').get(0)).remove();
		
		var pageNav = [];
		//render pagenav and hid lines
		opt.container.find('.data').each(function(i){
			var _mt = parseInt($(this).data('hidlines')) * opt.lineHeight;
			if(!_mt) _mt = 0;
			$(this).find('.line').get(0).style.marginTop = '-'+ _mt +'em';
			var _pn = i+1;
			var iscurrent = _pn === 1 ? 'on' : '';
			pageNav.push('<a class="topn '+iscurrent+'" href="#item'+_pn+'">第'+_pn+'页</a>');			
		});
		opt.nav.html(pageNav.join(''));
		opt.nav.data('index',1);
		window.location.hash = 'item1';
	};
	
	// Events for nav
	opt.nav.delegate('.topn','click',function(e){
		//e.preventDefault();
		var pn = utils.gethash(e);
        pn = parseInt(pn.replace('item',''));
        utils.go2page(pn);
	});
	//Event for keyCode nav
	var go2prev = function(){
		var idx = parseInt(window.location.hash.replace('#item',''));
		var p = idx - 1;
		//db(p);
		if(p > 0){
			utils.go2page(p);
		}else{
			return;
		}
	},
	go2next = function(){
		//db(window.location.hash.replace('#item',''));
		var idx = parseInt(window.location.hash.replace('#item',''));
		var p = idx + 1;
		//db(p);
		if(p <= pn){
			utils.go2page(p);
		}else{
			return;
		}
	};
	$(document).bind('keydown',function(e){
		var c = (e.charCode) ? e.charCode : e.keyCode;
			switch (c){
				case 37: go2prev(p2);return false;//[<-]
				case 39: go2next(p2);return false;//[->]
				case 38: go2prev();return false;//[^]
				case 40: go2next();return false;//[V]
				case 75: go2prev();return false;//[k]
				case 74: go2next();return false;//[j]
				//default: alert(e.keyCode);
			}
	});
	//Event for zoom
	$('.btn-zoom').click(function(e){
		e.preventDefault();
		type = utils.gethash(e);
		$('html').get(0).className = type;
	});
	//Event for scroll
	function check(){
		var scr_top = parseInt($(window).scrollTop() - $('#page-box').offset().top);
		db(scr_top);
		var el_page = $('#page-box .page-item').get(0);
		var perH = $(el_page).outerHeight(true);
		var _pn = Math.floor(scr_top / perH);
		
		var _lantency = null,_layTime = 1000;
		_lantency = setTimeout(function() {
			for(var i = 0 ; i < pn ; i++){
				if (i == _pn) {
					var idx = i+1;
					$('.topn').removeClass('on');
			  		$('.topn').eq(idx-1).addClass('on');
			  		//window.location.hash = 'item'+idx;
			  		opt.nav.data('index',idx);
				}
			}
		}, _layTime);
	}
	$(window).scroll(check);
	return {
		init : function(html){
			renderPage(html);
		}
	};
}());